﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SystemModule;
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using NetFramework.AsyncSocketClient;

namespace TestProject
{
    class Program
    {
        public static List<string> m_CanJmpScriptLableList;

        /// <summary>
        /// 补 "0"方法.
        /// </summary>
        /// <param name="zeroCounts">生成个数.</param>
        /// <returns></returns>
        /// <Author> frd  2011-11-2511:06</Author>
        private static string CreateZeros(int zeroCounts)
        {
            string Result = string.Empty;
            if (zeroCounts == 0)
            {
                Result = "";
                return Result;
            }
            for (int i = 0; i < zeroCounts; i++)
            {
                Result += "0";
            }
            return Result;
        }

        public unsafe static byte[] SendDBSockMsg(int nQueryID, string sMsg)
        {
            string sSENDMSG;
            int nCheckCode;
            string sCheckStr = string.Empty;
            nCheckCode = HUtil32.MakeLong(nQueryID ^ 170, sMsg.Length + 6);
            byte[] by = new byte[sizeof(int)];
            fixed (byte* pb = by)
            {
                *(int*)pb = nCheckCode;
            }
            sCheckStr = EncryptUnit.EncodeBuffer(by, by.Length);
            sSENDMSG = "#" + nQueryID + "/" + sMsg + sCheckStr + "!";

            byte[] data = System.Text.Encoding.Default.GetBytes(sSENDMSG);
            return HUtil32.StrToByte(sSENDMSG);
        }

        public static byte[] StructToBytes(object structObj)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(structObj);
            //创建byte数组
            byte[] bytes = new byte[size];
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷到分配好的内存空间
            Marshal.StructureToPtr(structObj, structPtr, false);
            //从内存空间拷到byte数组
            Marshal.Copy(structPtr, bytes, 0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回byte数组
            return bytes;
        }

        unsafe static void Main(string[] args)
        {
            var sHumanRcdStr = string.Empty;
            var sDBMsg = string.Empty;
            var sDBCharName = string.Empty;
            var sCharName = "123123";

            using (var sr = new System.IO.StreamReader("123456.txt"))
            {
                sHumanRcdStr = sr.ReadToEnd();
            }

            var sUserId = string.Empty;
            var sChrName = string.Empty;
            var sHumanRCD = GetValidStr3(sHumanRcdStr, ref sUserId, new string[] { "/" });
            sHumanRCD = GetValidStr3(sHumanRCD, ref sChrName, new string[] { "/" });
            sUserId = EncryptUnit.DeCodeString(sUserId);
            sChrName = EncryptUnit.DeCodeString(sChrName);

            var ddd = EncryptUnit.DecodeBuffer(sHumanRCD);
            var hum = new THumDataInfo(ddd);
        }

        static void socket_OnConnected(object sender, NetFramework.DSCClientConnectedEventArgs e)
        {
            Console.WriteLine("链接成功");
        }

        public struct Struct1
        {
            public int Id;
            public string Name;
        }

        [Serializable]
        public class Class1
        {
            public int Id;
            public string Name;
        }

        [StructLayout(LayoutKind.Auto)]
        public struct TProcessMessage
        {
            public int wIdent;
            public int wParam;
            public int nParam1;
            public int nParam2;
            public int nParam3;
            public int BaseObject;
            public bool boLateDelivery;
            public uint dwDeliveryTime;
            public String sMsg;
        }

        public unsafe static T[] ToByte<T>(void* source, int length)
        {
            var type = typeof(T);
            var sizeInBytes = Marshal.SizeOf(typeof(T));

            T[] output = new T[length];

            if (type.IsPrimitive)
            {
                // Make sure the array won't be moved around by the GC 
                var handle = GCHandle.Alloc(output, GCHandleType.Pinned);

                var destination = (byte*)handle.AddrOfPinnedObject().ToPointer();
                var byteLength = length * sizeInBytes;

                // There are faster ways to do this, particularly by using wider types or by 
                // handling special lengths.
                for (int i = 0; i < byteLength; i++)
                    destination[i] = ((byte*)source)[i];

                handle.Free();
            }
            else if (type.IsValueType)
            {
                if (!type.IsLayoutSequential && !type.IsExplicitLayout)
                {
                    throw new InvalidOperationException(string.Format("{0} does not define a StructLayout attribute", type));
                }

                IntPtr sourcePtr = new IntPtr(source);

                for (int i = 0; i < length; i++)
                {
                    IntPtr p = new IntPtr((byte*)source + i * sizeInBytes);

                    output[i] = (T)System.Runtime.InteropServices.Marshal.PtrToStructure(p, typeof(T));
                }
            }
            else
            {
                throw new InvalidOperationException(string.Format("{0} is not supported", type));
            }

            return output;
        }

        public static string unicode_0(string str)
        {
            string outStr = "";
            if (!string.IsNullOrEmpty(str))
            {
                for (int i = 0; i < str.Length; i++)
                {
                    outStr += "/u" + ((int)str[i]).ToString("x");
                }
            }
            return outStr;
        }
 

        public static int GetSize()
        {
            return 1 + 14 + 1 + 1 * 6 + 2 * 3 + 4 * 9;
        }

        public static string mSubString(string str, int StartIndex, int Count)
        {
            string ret = string.Empty;
            if (str == null)
                return ret;
            if (StartIndex >= str.Length)
                return ret;
            if (StartIndex < 0)
                StartIndex = 0;
            if (StartIndex + Count > str.Length)
                Count = str.Length - StartIndex;
            if (Count < 1)
                return ret;

            ret = str.Substring(StartIndex, Count);
            return ret;
        }

        private static ushort MakeWord(byte bLow, byte bHigh)
        {
            return (ushort)(bLow | (bHigh << 8));
        }

        public static string GetValidStr3(string Str, ref string Dest, string[] DividerAry)
        {
            char[] Div = new char[DividerAry.Length];
            int i;
            for (i = 0; i < DividerAry.Length; i++)
            {
                Div[i] = DividerAry[i][0];
            }

            string[] Ary = Str.Split(Div, 2, StringSplitOptions.RemoveEmptyEntries);
            if (Ary.Length > 0)
                Dest = Ary[0];
            else
                Dest = "";
            if (Ary.Length > 1)
                return Ary[1];
            else
                return "";
        }

        public static void GetScriptLabel(string sMsg)
        {
            string sText = string.Empty;
            string sData = string.Empty;
            string sCmdStr = string.Empty;
            string sLabel = string.Empty;
            try
            {
                m_CanJmpScriptLableList.Clear();
                while (true)
                {
                    if (sMsg == "")
                    {
                        break;
                    }
                    sMsg = GetValidStr3(sMsg, ref sText, new string[] { "\\" });
                    //if (sText == "") {
                    //    sText = sMsg;
                    //}
                    if (sText != "")
                    {
                        sData = "";
                        while ((sText.IndexOf("<") > -1) && (sText.IndexOf(">") > -1) && (sText != ""))
                        {
                            if (sText[0] != '<')
                            {
                                sText = "<" + GetValidStr3(sText, ref sData, new string[] { "<" });
                            }
                            sText = ArrestStringEx(sText, "<", ">", ref sCmdStr);
                            sLabel = GetValidStr3(sCmdStr, ref sCmdStr, new string[] { "/" });
                            if (sLabel != "")
                            {
                                m_CanJmpScriptLableList.Add(sLabel);
                            }
                        }
                    }
                }
            }
            catch
            {
                //M2Share.MainOutMessage("{异常} TPlayObject.GetScriptLabel");
            }
        }

        public static string ArrestStringEx(string Source, string SearchAfter, string ArrestBefore, ref string ArrestStr)
        {
            string result = string.Empty;
            int srclen;
            bool GoodData;
            int I;
            int n;
            ArrestStr = "";
            if (Source == "")
            {
                result = "";
                return result;
            }
            try
            {
                srclen = Source.Length;
                GoodData = false;
                if (srclen >= 2)
                {
                    if (Source[0].ToString() == SearchAfter)
                    {
                        Source = Source.Substring(2 - 1, srclen - 1);
                        srclen = Source.Length;
                        GoodData = true;
                    }
                    else
                    {
                        n = Source.IndexOf(SearchAfter) + 1;
                        if (n > 0)
                        {
                            Source = Source.Substring(n + 1 - 1, srclen - n);
                            srclen = Source.Length;
                            GoodData = true;
                        }
                    }
                }
                if (GoodData)
                {
                    n = Source.IndexOf(ArrestBefore) + 1;//By John修正  Delphi字符串是从1开始,C#为0开始,导致c#得到字符串的长度少一位
                    if (n > 0)
                    {
                        ArrestStr = Source.Substring(1 - 1, n - 1);
                        result = Source.Substring(n + 1 - 1, srclen - n);
                    }
                    else
                    {
                        result = SearchAfter + Source;
                    }
                }
                else
                {
                    for (I = 1; I <= srclen; I++)
                    {
                        if (Source[I - 1].ToString() == SearchAfter)
                        {
                            result = Source.Substring(I - 1, srclen - I + 1);
                            break;
                        }
                    }
                }
            }
            catch
            {
                ArrestStr = "";
                result = "";
            }
            return result;
        }

        public unsafe static TDefaultMessage MakeDefaultMsg(int wIdent, int nRecog, int wParam, int wTag, int wSeries, int wSessionID)
        {
            TDefaultMessage result = new TDefaultMessage();
            result.Recog = nRecog;
            result.Ident = (ushort)wIdent;
            result.Param = wParam;
            result.Tag = wTag;
            result.Series = wSeries;
            result.nSessionID = wSessionID;
            return result;
        }

        public static string sub_49ADB8(string sMsg, string sStr, string sText)
        {
            string result;
            int n10;
            string s14;
            string s18;

            n10 = sMsg.IndexOf(sStr);
            if (n10 > -1)
            {
                s14 = sMsg.Substring(1 - 1, n10);
                s18 = sMsg.Substring(sStr.Length + n10, sMsg.Length - (sStr.Length + n10));
                result = s14 + sText + s18;
            }
            else
            {
                result = sMsg;
            }
            return result;

        }

        public static int MakeLong(int w, int s) { return (int)(((ushort)w) | (uint)(s << 16)); }
        

        // 思路：对于含有高字节不为0的，说明字符串包含汉字，用Encoding.Default.GetBytes
        //     这样会导致服务端string结构发生变化，但是不影响网络传输的数据
        // 对于高字节为0的，仅处理低字节
        // retby 为 null 表示仅计算长度并返回
        public unsafe static int StringToBytePtr(string str, byte* retby, int StartIndex)
        {
            bool bDecode = false;
            for (int i = 0; i < str.Length; i++)
            {
                if ((UInt16)str[i] >> 8 != 0)
                {
                    bDecode = true;
                    break;
                }
            }

            int nLen = 0;
            if (bDecode)
            {
                nLen = Encoding.Default.GetByteCount(str);
            }
            else
            {
                nLen = str.Length;
            }
            if (retby == null)
                return nLen;


            if (bDecode)
            {
                byte[] by = Encoding.Default.GetBytes(str);
                byte* pb = retby + StartIndex;
                for (int i = 0; i < by.Length; i++)
                    *(pb++) = by[i];
            }
            else
            {

                byte* pb = retby + StartIndex;
                for (int i = 0; i < str.Length; i++)
                {
                    *(pb++) = (byte)str[i];
                }
            }

            return nLen;
        }

        public unsafe static string BytePtrToString(byte* by, int StartIndex, int Len)
        {
            string ret = new string('\0', Len);
            StringBuilder sb = new StringBuilder(ret);

            by += StartIndex;
            for (int i = 0; i < Len; i++)
            {
                sb[i] = (char)(*(by++));
            }

            return sb.ToString();
        }

        public unsafe static string ByteAryToString(byte[] by, int StartIndex, int Len)
        {
            fixed (byte* pb = by)
            {
                return BytePtrToString(pb, StartIndex, Len);
            }
        }

        public unsafe static byte[] StringToByteAry(string str)
        {
            int nLen = StringToBytePtr(str, null, 0);
            byte[] ret = new byte[nLen];
            fixed (byte* pb = ret)
            {
                StringToBytePtr(str, pb, 0);
            }

            return ret;
        }

        public unsafe static string SByteAryToString(sbyte[] by, int StartIndex, int Len)
        {
            fixed (sbyte* pb = by)
            {
                return BytePtrToString((byte*)pb, StartIndex, Len);
            }
        }

        public unsafe static sbyte[] StringToSByteAry(string str)
        {
            int nLen = StringToBytePtr(str, null, 0);
            sbyte[] ret = new sbyte[nLen];
            fixed (sbyte* pb = ret)
            {
                StringToBytePtr(str, (byte*)pb, 0);
            }

            return ret;
        }

        public unsafe static string SBytePtrToString(sbyte* by, int StartIndex, int Len)
        {
            return BytePtrToString((byte*)by, StartIndex, Len);
        }

        public unsafe static int StringToSBytePtr(string str, sbyte* retby, int StartIndex)
        {
            int nLen = StringToBytePtr(str, null, 0);
            if (retby == null)
                return nLen;

            return StringToBytePtr(str, (byte*)retby, StartIndex);
        }

        public unsafe static string IntPtrToString(IntPtr by, int StartIndex, int Len)
        {
            return BytePtrToString((byte*)by, StartIndex, Len);
        }

        public unsafe static int StringToIntPtr(string str, IntPtr retby, int StartIndex)
        {
            return StringToBytePtr(str, (byte*)retby, StartIndex);
        }

        public unsafe static string IntPtrPlusLenToString(IntPtr by, int StartIndex)
        {
            byte* pb = (byte*)by + StartIndex;
            int nLen = *(int*)pb;

            string ret = new string('\0', nLen);
            StringBuilder sb = new StringBuilder(ret);

            pb += sizeof(int);
            for (int i = 0; i < nLen; i++)
                sb[i] = (char)pb[i];

            return sb.ToString();
        }

        public unsafe static int StringToIntPtrPlusLen(string str, IntPtr retby, int StartIndex)
        {
            int nLen = StringToBytePtr(str, null, 0);
            if (retby == (IntPtr)0)
                return nLen + sizeof(int);

            byte* pb = (byte*)retby + StartIndex;
            *(int*)pb = nLen;
            pb += sizeof(int);
            StringToBytePtr(str, pb, 0);

            return nLen + sizeof(int);
        }

    }
}
